package com.atwisdom.star.service.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.util.JsonUtil;
import com.atwisdom.star.common.util.UuidTool;
import com.atwisdom.star.core.dao.pojo.modelClass.consume.ConsumeInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.logic.LogicInstance;
import com.atwisdom.star.core.dao.pojo.modelClass.resource.ResourceInstance;
import com.atwisdom.star.core.dsl.modelClass.consume.Impl.ConsumeInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.hier.HierInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.logic.Impl.LogicInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.resource.Impl.ResourceInstanceDslServiceImpl;
import com.atwisdom.star.core.dsl.modelClass.routing.Impl.RoutingInstanceDslServiceImpl;
import com.atwisdom.star.exception.pojo.BusinessException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName: LogicUtil
 * @ Description: logic定制化处理操作
 * @author: 王红艳
 * @date:
 */
@Service
public class LogicUtil {
    @Autowired
    private LogicInstanceDslServiceImpl logicInstanceDslService;

    @Autowired
    private HierInstanceDslService hierInstanceDslService;

    @Autowired
    private ConsumeUtil consume;

    @Autowired
    private ResourceUtil resource;

    @Autowired
    private ConsumeInstanceDslServiceImpl consumeInstanceDslServiceImpl;

    @Autowired
    private ResourceInstanceDslServiceImpl resourceInstanceDslServiceImpl;

    @Autowired
    private RoutingInstanceDslServiceImpl routingInstanceDslServiceImpl;

    /**
     * 根据条件查询符合则返回不符合则新增返回
     * @param className 对象名称
     * @param type 对象类型
     * @param values 对象字段
     * @return 查询或新增实例
     */
    public JSONObject queryUpdateOrAdd(String className, String type, JSONObject values, String ...linkKeys){
        String condition = "className=='"+className+"'&&type=='"+type+"'";
        if(ObjectUtil.isAllNotEmpty(linkKeys)){
            for (String LinkKey:linkKeys){
                if(values.get(LinkKey) instanceof String){
                    condition = condition + "&&"+LinkKey+"=='"+values.get(LinkKey)+"'";
                }else{
                    condition = condition + "&&"+LinkKey+"=="+values.get(LinkKey)+" ";
                }
            }
        }
        List<JSONObject> insList = this.logicInstanceDslService.query(condition,className);
        if(insList.size()>0){
            JSONObject ins = insList.get(0);
            boolean updateFlag = false;
            for(String key:values.keySet()){
                if(ObjectUtil.isNotEmpty(values.get(key))&&values.get(key)!=ins.getJSONObject("values").getString(key)){
                    updateFlag = true;
                    break;
                } else if (ObjectUtil.isEmpty(values.get(key)) && ObjectUtil.isNotEmpty(ins.getJSONObject("values").get(key))) {
                    updateFlag = true;
                    break;
                }
            }
            if(updateFlag){
                return logicInstanceDslService.updateById(JsonUtil.buildJson(new Object[] {"id",ins.getLong("id"),"className",className,"type",type,"values",values}));
            }
            return ins;
        }else{
            return this.logicInstanceDslService.add(type,className,String.valueOf(System.currentTimeMillis()),values);
        }
    }

    /**
     * 根据id查询实例，并将hier中的实例数据查询出来展示
     * @param id
     * @return
     */
    public JSONObject queryByIdAndHier(Long id){
        LogicInstance logicInstance = logicInstanceDslService.queryInsWithHierById(id);
        logicInstance.getHierInstances().forEach(hierInstance -> {
            JSONObject values = hierInstance.getValues();
            JSONObject json = new JSONObject();
            if(null!=hierInstance.getLinkId()&&"logic".equals(hierInstance.getLinkModel())){
                json = logicInstanceDslService.queryJsonById(hierInstance.getLinkId());
            }
            if(null!=hierInstance.getLinkId()&&"resource".equals(hierInstance.getLinkModel())){
                json = resourceInstanceDslServiceImpl.queryById(hierInstance.getLinkId());
            }
            if(null!=hierInstance.getLinkId()&&"consume".equals(hierInstance.getLinkModel())){
                json = consumeInstanceDslServiceImpl.queryById(hierInstance.getLinkId());
            }
            if(null!=hierInstance.getLinkId()&&"routing".equals(hierInstance.getLinkModel())){
                json = routingInstanceDslServiceImpl.queryJsonById(hierInstance.getLinkId());
            }
            if(CollectionUtil.isNotEmpty(json)){
                hierInstance.setValues(json.getJSONObject("values"));
            }
        });
        return logicInstanceDslService.getLogicInsJsonObjectList(Arrays.asList(logicInstance)).get(0);
    }
    /**
     * 复制实例
     * @param id 实例id
     * @param newValues 要更新的值
     * @return 复制新增的实例json
     */
    public JSONObject copyIns(Long id,JSONObject newValues){
        JSONObject logicIns = logicInstanceDslService.queryJsonById(id);
        if(null==logicIns){
            return null;
        }
        JSONObject values = logicIns.getJSONObject("values");
        /*values.put("if_template",logicIns.getIntValue("id"));
        values.put("bf_template",0);
        values.put("sf_status","创建");*/
        values.putAll(newValues);
        LogicInstance copyIns = JsonUtil.toJavaBean(logicInstanceDslService.add(logicIns.getString("type"),logicIns.getString("className"),UuidTool.getUUID32(),values),LogicInstance.class);
        return logicInstanceDslService.queryJsonById(copyIns.getId());
    }

    /**
     * 1.获取pointer。命名新的Bean，if_Template指向pointer的id,bf_Template设为false
     * 2.获取新的Bean的Basic，遍历Basic，获取pointer执行的实例，命名新的Bean，处理方式同1
     * 复制执行数据
     * @param id 要复制的数据id
     */
    public JSONObject copyContainer(Long id){
        JSONObject logicIns = logicInstanceDslService.queryJsonById(id);
        JSONObject values = logicIns.getJSONObject("values");
        values.put("if_template",logicIns.getIntValue("id"));
        values.put("bf_template",0);
        values.put("sf_status","创建");
        LogicInstance copyIns = JsonUtil.toJavaBean(logicInstanceDslService.add(logicIns.getString("type"),logicIns.getString("className"),UuidTool.getUUID32(),values),LogicInstance.class);
        handleHier(copyIns  ,logicIns.getLong("id"));
        return logicInstanceDslService.queryJsonById(copyIns.getId());
    }

    /**
     * 处理复制执行数据的hier数据
     * @param newLogicIns
     * @param id
     */
    private void handleHier(LogicInstance newLogicIns,Long id) {
        JSONArray  basic = getHierBlock(logicInstanceDslService.queryHierById(id),"");
        if (basic == null) {
            // 如果获取的基本数据为空，则直接返回，避免空指针异常
            return;
        }
        for(int i=0;i<basic.size();i++){
            JSONObject item = basic.getJSONObject(i);
            if(null==JsonUtil.get(item,"link.linkId")){
                continue;
            }
            Long linkId = item.getJSONObject("link").getLong("linkId");
            String linkModel = item.getJSONObject("link").getString("linkModel");
            String parentId = item.getString("parentId");
            copyAddRegisterBean(linkId,linkModel,parentId,newLogicIns);
        }
    }

    /**
     *
     * @param linkId
     * @param model
     * @param parentId
     * @param newLogicIns
     */
    private void copyAddRegisterBean(Long linkId,String model,String parentId,LogicInstance newLogicIns){
        if("resource".equals(model)){
            ResourceInstance newBean = JsonUtil.toJavaBean(resource.copyIns(linkId,new JSONObject()),ResourceInstance.class);
            addHier(parentId, newLogicIns.getId(), newBean.getId(),newBean.getValues());
        }else if("consume".equals(model)){
            ConsumeInstance newBean = JsonUtil.toJavaBean(consume.copyIns(linkId,new JSONObject()),ConsumeInstance.class);
            addHier(parentId, newLogicIns.getId(), newBean.getId(),newBean.getValues());
        }else if("logic".equals(model)){
            LogicInstance newBean = JsonUtil.toJavaBean(copyContainer(linkId),LogicInstance.class);
            //关联到hier
            addHier(parentId, newLogicIns.getId(), newBean.getId(),newBean.getValues());
        }else{
            throw new BusinessException("500","model类型错误");
        }
    }

    /**
     * 增加hier数据
     * @param parentId
     * @param containerId
     * @param newLinkId
     */
    public void addHier(String parentId, Long containerId, Long newLinkId,JSONObject values) {
        values.put("linkId",newLinkId);
        JSONObject linkJson = JsonUtil.buildJson(new Object[]{"containerModel","logic","containerId",containerId,"parentId",parentId,"linkId",newLinkId,"values",values});
        hierInstanceDslService.addChild(linkJson);
    }

    /**
     * @description:需要验证hier不为空
     * @param hier: 逻辑实例hier数据
     * @param parentId:hier中的键名
     * @return: JSONArray
     * @author Why
     * @date: 2024/4/17 1:22
     */
    public JSONArray getHierBlock(JSONObject hier, String parentId){
        if(hier.containsKey("content")){
            if(StrUtil.isEmpty(parentId)){
                return hier.getJSONArray("content");
            }
            return JsonUtil.toJSONArray(hier.getJSONArray("content").stream()
                    .filter(item->parentId.equals(JsonUtil.toJSONObject(item).getString("parentId")))
                    .collect(Collectors.toList()));
        }else{
            throw new BusinessException("500","Hier中不存数据");
        }
    }
}
